package lk.icta.core.dao;

import lk.icta.core.entity.Alienation;
import lk.icta.core.entity.AlienationMethod;
import lk.icta.core.entity.LandAssociation;
import lk.icta.user.entity.User;

import java.util.List;

/**
 * @author Duminda Dharmakeerthi
 */
public interface AlienationDAO {

    /**
     * Add an Alienation
     *
     * @param alienation The Alienation to be added
     * @param user       The user requesting to add the alienation
     */
    public void addAlienation(Alienation alienation, User user);

    /**
     * Update an Alienation
     *
     * @param alienation The alienation to be updated
     * @param user       The user requesting to update the alienation
     */
    public void updateAlienation(Alienation alienation, User user);

    /**
     * Delete an Alienation
     *
     * @param alienation Alienation to be deleted
     * @param user       User requesting to delete the alienation
     */
    public void deleteAlienation(Alienation alienation, User user);

    public void deleteAlienationFromDatabase(long alienationId, User user);

    public void removeAlienation(long id, User user);

    /**
     * Add Land Alienation Methods to lands
     *
     * @param LAMMetadata Alienation Metadeta to be persist
     * @param user        user who performs this action
     */
    public void addLandAlienationMetadata(LandAssociation LAMMetadata, User user);

    /**
     * Find alienation by Alienation Id
     *
     * @param id   The Alienation Id
     * @param user The user requesting to find the alienation
     * @return An alienation corresponding to the given id
     */
    public Alienation getAlienationById(Long id, User user);

    /**
     * Returns a list of Alienation records of a land
     *
     * @param landId The Id of the land
     * @param user   The user requesting the search
     * @return List of alienation related to the given land
     */
    public List<Alienation> getAlienationByLand(Long landId, User user);

    /**
     * Returns a list of alienation records of a person
     *
     * @param holderId The id of the person
     * @param user     The user requesting to list alienation
     * @return List of alienation related to the given person
     */
    public List<Alienation> getAlienationByHolder(Long holderId, User user);

    /**
     * List all alienation records
     *
     * @param user The user requesting to list alienation records
     * @return List of all alienation records
     */
    public List<Alienation> getAllAlienation(User user);

    /**
     * List all active alienation records
     *
     * @param user User requesting to list alienation
     * @return List of all active alienation
     */
    public List<Alienation> getAllActiveAlienation(User user);

    /**
     * Returns the ACTIVE Alienation of the land
     *
     * @param landId Id of the land
     * @param user   User requesting to find the alienation
     * @return ACTIVE Alienation of the land
     */
    public Alienation getActiveAlienationByLandId(long landId, User user);

    public Alienation getPendingAlienationByLandId(long landId, User user);

    /**
     * Returns list of all alienation related to a grant
     *
     * @param grantId Grant Id
     * @param user    User requesting to list alienation history
     * @return List of alienation related to the given grant
     */
    public List<Alienation> getGrantAlienationHistory(long grantId, User user);

    /**
     * Returns list of all active alienation related to given GN Division
     *
     * @param gnDivisionId G.N. Division
     * @param user         User requesting to get alienation list.
     * @return List of alienation related to the given G.N. Division.
     */
    public List<Alienation> getActiveAlienationByGNDivision(int gnDivisionId, User user);

    /**
     * Find alienation method by alienation Id
     *
     * @param id   Alienation Id
     * @param user The user who performs this action
     * @return The Alienation Method corresponding to the given id
     */
    public AlienationMethod getAlienationMethodById(int id, User user);

    /**
     * Returns list of children alienation of given alienation
     *
     * @param parentId Id of the alienation
     * @param user     User requesting to list children
     * @return List of child nodes
     */
    public List<Alienation> getChildAlienationNodesByParentId(long parentId, User user);

    /**
     * Returns list of alienation related to given alienation method
     *
     * @param alienationMethod Alienation method
     * @param user             User requesting to list alienation
     * @return List of alienation
     */
    public List<Alienation> getAlienationByAlienationMethod(int alienationMethod, User user);

    public List<Alienation> getAllAlienationByAlienationMethod(int alienationMethod, User user);


    /**
     * Returns the ACTIVE Alienation of the permit no
     *
     * @param referenceNo permit number of the alienation
     * @return ACTIVE Alienation of the land
     */
    public Alienation getActiveAlienationByReferenceNo(String referenceNo);

    /**
     * Returns the ACTIVE ApprovedAlienation of the permit no
     *
     * @param referenceNo permit number of the alienation
     * @return ACTIVE Alienation of the land
     */
    public Alienation getActiveApprovedAlienationByReferenceNo(String referenceNo);

    /**
     * Check whether an alienation exists with the given reference
     *
     * @param referenceNo Reference no to be checked
     * @return TRUE if reference exists. FALSE otherwise
     */
    public Boolean isExistsReference(String referenceNo);

    public List<Alienation> searchPermit(User user);

    /**
     * Returns the State=Pending Alienation of the alienation id
     *
     * @param alienationId permit number of the alienation
     * @return Pending Alienation of the land
     */
    public List<Alienation> getPendingAlienationByAlienationMethod(int alienationId, User user);
}
